package simpledb;

import java.io.IOException;

/**
 * The delete operator. Delete reads tuples from its child operator and removes
 * them from the table they belong to.
 */
public class Delete extends Operator {

    private static final long serialVersionUID = 1L;

    private TransactionId transactionId;
    private OpIterator child;

    private int cnt;
    private TupleDesc tupleDesc;
    private boolean isCalled;

    /**
     * Constructor specifying the transaction that this delete belongs to as
     * well as the child to read from.
     * 
     * @param t
     *            The transaction this delete runs in
     * @param child
     *            The child operator from which to read tuples for deletion
     */
    public Delete(TransactionId t, OpIterator child) {
        // some code goes here
        transactionId=t;
        this.child =child;

        tupleDesc=new TupleDesc(new Type[]{Type.INT_TYPE});
        cnt=-1;
        isCalled=false;
    }

    @Override
    public TupleDesc getTupleDesc() {
        // some code goes here
        return tupleDesc;
    }

    @Override
    public void open() throws DbException, TransactionAbortedException {
        // some code goes here
//        System.out.println("call Delete.open");
        super.open();
        child.open();
        cnt=0;
    }

    @Override
    public void close() {
        // some code goes here
        super.close();
        child.close();
        cnt=-1;
        isCalled=false;
    }

    @Override
    public void rewind() throws DbException, TransactionAbortedException {
        // some code goes here
        super.close();
        super.open();
        child.rewind();
        cnt=0;
        isCalled=false;
    }

    /**
     * Deletes tuples as they are read from the child operator. Deletes are
     * processed via the buffer pool (which can be accessed via the
     * Database.getBufferPool() method.
     * 
     * @return A 1-field tuple containing the number of deleted records.
     * @see Database#getBufferPool
     * @see BufferPool#deleteTuple
     */
    @Override
    protected Tuple fetchNext() throws TransactionAbortedException, DbException {
        // some code goes here
//        System.out.println("call Delete.fetchNext");
        if (isCalled){
            return null;
        }
        isCalled=true;
        while (child.hasNext()){
            Tuple next=child.next();
            try {
                Database.getBufferPool().
                        deleteTuple(transactionId,next);
                cnt++;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        Tuple tuple=new Tuple(tupleDesc);
        tuple.setField(0,new IntField(cnt));
        return tuple;
    }

    @Override
    public OpIterator[] getChildren() {
        // some code goes here
        OpIterator[]opIterators={child};
        return opIterators;
    }

    @Override
    public void setChildren(OpIterator[] children) {
        // some code goes here
        child=children[0];
    }

}
